#ifndef __DRIVER_H
#define __DRIVER_H
#include "stdtype.h"
#include "error.h"
#include "carray.h"
#include "mutex.h"
#include "device.h"

/**
 * the descriptor of driver operation (unify)
 */
typedef mx_device_ops_t mx_driver_ops_t, *mx_driver_ops_pt;

struct mx_driver;
typedef struct mx_driver mx_driver_t, *mx_driver_pt;

/**
 * the descriptor of driver events
 */
typedef struct
{
    void (*onmount) (mx_driver_pt pdrv);        // called when the driver install (can be null)
    void (*onumount) (mx_driver_pt pdrv);       // called when remove the driver (can be null)
    mx_bool_t (*onlinkup) (mx_driver_pt pdrv, mx_device_pt pdev);   // called when a device matches the driver (whatever who install first)
    void (*onlinkdown) (mx_driver_pt pdrv, mx_device_pt pdev);      // called when a device or driver remove from the system
} mx_driver_events_t, *mx_driver_events_pt;

/**
 * the descriptor of driver
 */
struct mx_driver
{
    mx_string_pt name;          // the driver name use for match with the device which with the same name(drvname)

    mx_carray_node_t node;      // an node of driver list
    mx_carray_t devbase;        // the device list which matched this driver

    mx_void_pt data;            // the private data of driver

    mx_driver_ops_pt ops;       // unified operations of driver for app
    mx_void_pt cusops;          // custom operations for personalized function

    mx_driver_events_pt events;
};

/* mount a driver to system */
void mx_driver_mount (mx_driver_pt pdrv, mx_string_pt name, mx_driver_ops_pt ops,
                      mx_void_pt cusops, mx_driver_events_pt events, mx_void_pt data);
/* umount a driver from system */
mx_err_t mx_driver_umount (mx_driver_pt pdrv);
/* get the count of driver in system */
mx_usize_t mx_driver_count ();
/* get driver by name */
mx_driver_pt mx_driver_get (mx_string_pt name);

#endif
